

<!DOCTYPE html>
<html lang="zh" data-default-color-scheme=&#34;auto&#34;>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/walker_sue/img/favicon.png">
  <link rel="icon" type="image/png" href="/walker_sue/img/favicon.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="">
  <meta name="author" content="lk">
  <meta name="keywords" content="">
  <title>时间序列分析（一） - Walker_Sue</title>

  <link  rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.staticfile.org/github-markdown-css/4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/walker_sue/lib/hint/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/10.0.0/styles/github-gist.min.css" />
    
  

  


<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">


<link  rel="stylesheet" href="/walker_sue/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script  src="/walker_sue/js/utils.js" ></script>
  <script  src="/walker_sue/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 5.3.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/walker_sue/">&nbsp;<strong>Walker</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/walker_sue/">
                <i class="iconfont icon-home-fill"></i>
                主页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/walker_sue/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/walker_sue/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/walker_sue/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/walker_sue/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <i class="iconfont icon-books"></i>
                文档
              </a>
              <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://hexo.fluid-dev.com/">
                    
                    主题博客
                  </a>
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://hexo.fluid-dev.com/docs/guide/">
                    
                    配置指南
                  </a>
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://hexo.fluid-dev.com/docs/icon/">
                    
                    图标用法
                  </a>
                
              </div>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;</a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" href="javascript:">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner intro-2" id="background" parallax=true
         style="background: url('/walker_sue/img/default.png') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="container page-header text-center fade-in-up">
    <span class="h2" id="subtitle">
    
</span>




<div class="mt-3">
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2020-12-30 13:31" pubdate>
        December 30, 2020 pm
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      7.1k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      84
       分钟
    </span>
  

  
  
</div>


</div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid">
  <div class="row">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-md">
      <div class="container nopadding-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto" id="post">
            <!-- SEO header -->
            <h1 style="display: none">时间序列分析（一）</h1>
            
            <div class="markdown-body" id="post-body">
              <div align='center' ><font size='10'>机器学习-BI</font></div>

<hr>
<div align='center' ><font size='5'>Week_01</font></div>
<div align='center' ><font size='5'>时间序列分析</font></div>

<hr>
<p><img src="bi_overview1.png" srcset="/walker_sue/img/loading.gif"><br><img src="bi_overview2.png" srcset="/walker_sue/img/loading.gif"></p>
<blockquote>
<p><strong>Outline</strong></p>
<ul>
<li>时间序列的概念</li>
<li>时间序列的基本特性及其分解</li>
<li>时间序列分析的常用统计模型：AR、MA、ARMA、ARIMA</li>
<li>LSTM进行时间序列预测</li>
<li>PM2.5数据基于时序预测的实现</li>
<li>时序数据库</li>
</ul>
</blockquote>
<p><img src="outline1.png" srcset="/walker_sue/img/loading.gif"><br><img src="outline2.png" srcset="/walker_sue/img/loading.gif"></p>
<h2 id="一、时间序列概念"><a href="#一、时间序列概念" class="headerlink" title="一、时间序列概念"></a>一、时间序列概念</h2><p>时间序列定义: 按时间顺序排列的随机变量序列。          观测样本: 时间序列各随机变量的观测样本。一定是有限多个。<br><br>一次实现(一条轨道): 时间序列的一组实际观测。          时间序列分析的任务: 数据建模，解释、控制或预报。<br>记号: ${X_t}$. <br><br><img src="time1.png" srcset="/walker_sue/img/loading.gif"><br>时间序列分析与回归分析的区别：</p>
<ul>
<li>在选择模型前，我们需要确定结果与变量之间的关系。回归分析训练得到的是目标变量y与自变量x（一个或多个）的相关性，然后通过新的自变量x来预测目标变量y。而时间序列分析得到的是目标变量y与时间的相关性</li>
<li>回归分析擅长的是多变量与目标结果之间的分析，即便是单一变量，也往往与时间无关。而时间序列分析建立在时间变化的基础上，它会分析目标变量的趋势、周期、时期和不稳定因素等。这些趋势和周期都是在时间维度的基础上，是我们要观察的重要特征</li>
</ul>
<h2 id="二、时间序列的基本特性及其分解"><a href="#二、时间序列的基本特性及其分解" class="headerlink" title="二、时间序列的基本特性及其分解"></a>二、时间序列的基本特性及其分解</h2><p>$${X_t} = {T_t} + {S_t} + {R_t},t=1,2,3,…$$ <br></p>
<p><img src="time2.png" srcset="/walker_sue/img/loading.gif"></p>
<h3 id="2-1-时间序列分解"><a href="#2-1-时间序列分解" class="headerlink" title="2.1 时间序列分解"></a>2.1 时间序列分解</h3><p><strong>(1) 平稳序列时间序列（stationary series）</strong> <br><br>是基本上不存在趋势的序列，序列中的各观察值基本上在某个固定的水平上波动，在不同时间段波动程度不同，但不存在某种规律，随机波动。它们的均值和方差是常数，对于这类序列，有成熟的模型来拟合这个序列在未来的发展状况，如AR，MA，ARMA等（具体模型算法及实现在后面）<br><br>(平稳序列)数学定义：如果时间序列${X_t}$ = {${X_t}$:t $\in$ N}满足<br></p>
<blockquote>
<ul>
<li>1.对于任何 t $\in$ N,${E{X_t}^2 &lt; \infty}$;<br></li>
</ul>
</blockquote>
<ul>
<li>2.对于任何 t $\in$ N,${E{X_t} = \mu}$;<br></li>
<li>3.对于任何 t,s $\in$ N,${(E[{X_t}-\mu)(E[{X_t}-\mu)}] = \gamma_{t-s}$,则称${X_t}$是平稳时间序列, 简称为平稳序列或平稳列. 称实数列${\gamma_t}$为${X_t}$的自协方差函数.<br></li>
</ul>
<p>性质:<br></p>
<blockquote>
<ul>
<li>期望、方差与无关。</li>
</ul>
</blockquote>
<ul>
<li>时间平移不影响两时刻的相关系数。</li>
<li>又称平稳序列为二阶矩平稳序列, 还称为宽平稳列或弱平稳列。</li>
</ul>
<p><strong>(2) 非平稳序列（non-stationary series）</strong><br><br>是包含趋势、季节性或周期性的序列，只含有其中一种成分，也可能是几种成分的组合。可分为：有趋势序列、有趋势和季节性序列、几种成分混合而成的复合型序列。</p>
<ul>
<li><strong>趋势（trend）</strong>：时间序列在长时期内呈现出来的某种持续上升或持续下降的变动，也称长期趋势。时间序列中的趋势可以是线性和非线性。趋势的估计可以使用：每年平均；线性回归拟合直线；二次曲线回归；滑动平均估计；</li>
<li><strong>季节性（seasonality）</strong>：季节变动（seasonal fluctuation）,是时间序列在一年内重复出现的周期波动。销售旺季，销售淡季，旅游旺季、旅游淡季，因季节不同而发生变化。季节，不仅指一年中的四季，其实是指任何一种周期性的变化。含有季节成分的序列可能含有趋势，也可能不含有趋势。</li>
<li><strong>周期性（cyclicity）</strong>：循环波动（cyclical fluctuation），是时间序列中呈现出来的围绕长期趋势的一种波浪形或振荡式波动。周期性是由商业和经济活动引起的，不同于趋势变动，不是朝着单一方向的持续运动，而是涨落相间的交替波动；不同于季节变动，季节变动有比较固定的规律，且变动周期大多为一年，循环波动则无固定规律，变动周期多在一年以上，且周期长短不一。周期性通常是由经济环境的变化引起。</li>
<li><strong>随机性（Irregular）</strong>:指受偶然因素影响所形成的的不规则波动，在时间序列中无法预估。随机性是不规则波动，除去趋势、周期性、季节性的偶然性波动。<br></li>
</ul>
<p><strong>(3) 纯随机序列（白噪声序列）</strong><br><br>白噪声的称谓来自物理学中，表示接收到的信号中没有信息，全部为噪声。白噪声序列的特点表现在任何两个时点的随机变量都不相关，序列中没有任何可以利用的动态规律，因此不能用历史数据对未来进行预测和推断。这时候可以停止分析，因为就像预测下一次硬币哪一面朝上一样毫无规律。<br><br> (白噪声)数学定义:设${\epsilon_t}$是一个平稳序列. 如果对任何s,t ${\in}$ N 有: <br></p>
<p> $$E{\epsilon_t} = \mu,$$ <br><br> $$Cov({\epsilon_t},{\epsilon_s}) = {\sigma^2}{\delta_{t-s}} = \begin{cases}<br> {\sigma^2},\quad t = s; \<br> 0,\quad t \neq  s;<br> \end{cases}$$  <br><br>则称{${\epsilon_t}$}是一个<strong>白噪声</strong>, 记做WN(${\mu,{\sigma^2}}$). <br><br>设{${\epsilon_t}$}是白噪声, 当{${\epsilon_t}$}是<strong>独立序列时</strong>, 称{${\epsilon_t}$}是独立白噪声。<br>当$\mu=0$时, 称{${\epsilon_t}$}为<strong>零均值白噪声</strong>。</p>
<h3 id="2-2-时间序列统计分析"><a href="#2-2-时间序列统计分析" class="headerlink" title="2.2 时间序列统计分析"></a>2.2 时间序列统计分析</h3><h4 id="2-2-1-平稳性检验"><a href="#2-2-1-平稳性检验" class="headerlink" title="2.2.1 平稳性检验"></a>2.2.1 平稳性检验</h4><p>${\quad}$平稳性是时间序列分析的基础。<br><br>${\quad}$平通俗的理解平稳性，指直观上看当数据没有明显的模式特征的话（趋势性、季节性），我们认为它是平稳的。定义上“平稳”指固定时间和位置的概率分布与所有时间和位置的概率分布相同的随机过程。其数学期望和方差这些参数也不随时间和位置变化。<br><br>${\quad}$平在数学上，时间序列的严平稳有着更精确的定义：它要求时间序列中任意给定长度的两段子序列都满足相同的联合分布。这是一个很强的条件，在实际中几乎不可能被满足。因此我们还有弱平稳的定义，<strong>它要求时间序列满足均值平稳性和二阶平稳性</strong>。<br><br>平如果一个时间序列满足以下两个条件，则它是弱平稳的：</p>
<ul>
<li>对于所有的时刻t，有图片，其中μ是一个常数。</li>
<li>对于所有的时刻t和任意的间隔k，值之间的协方差图片，其中图片与时间t无关，它仅仅依赖于间隔k。这称为方差平稳性。</li>
</ul>
<p>${\quad}$平<strong>弱平稳假设对于分析时间序列至关重要。</strong></p>
<h4 id="2-2-3-自相关性检验-ACF"><a href="#2-2-3-自相关性检验-ACF" class="headerlink" title="2.2.3 自相关性检验(ACF)"></a>2.2.3 自相关性检验(ACF)</h4><p>${\quad}$时间序列数据是一直延伸的，根据这种数据特点，一般需要我们拿当前数据与历史数据做对比，即自相关性检验。自相关性则是指一个时间序列的两个不同时间点的变量是否相关联。时间序列具有自相关性是我们能够进行分析的前提，若时间序列的自相关性为0，也就是说各个时点的变量不相互关联，那么未来与现在和过去就没有联系，根据过去信息来推测未来就变得毫无根据。时间序列的自相关性一般用时间序列的自协方差函数、自相关系数函数和偏自相关系数函数等统计量来衡量。<br><br><strong>自协方差函数</strong><br>自协方差（Autocovariance,简称AF）是时间序列与其滞后项的协方差，假设X为随机变量（即随着时间变化取值随机的变量,比如股票价格），则k阶自协方差使用数学公式表示为：<br><br>其中，E表示求数学期望，u是随机变量X的均值，当k=0时，可得</p>
<p>$${AF_k} = E[(X_t - \mu_t)(X_{t-k} - \mu_{t-k})] = Cov(X_t,X_{t-k},k=0,1,2,…) $$</p>
<p>即为随机变量X的方差。<br>$$AF_0 = E[(X_t - \mu_t)^2]$$<br><strong>自相关函数</strong><br>自协方差跟变量的单位有很大关系，比如X放大10倍，则自协方差将放大100倍，因此其值大小并不能反映相关性的大小。为了消除量纲（单位）的影响，使用自相关系数来刻画变量与其滞后项的相关性。自相关系数（Autocorrelation Coefficient，简称ACF）本质是相关系数，等于自协方差除以方差，k阶自相关系数数可以表示为：<br>$${ACF_k} = \frac{Cov(X_t,X_{t-k})}{Var(X_t)}$$</p>
<h4 id="2-2-3-偏自相关函数-PACF"><a href="#2-2-3-偏自相关函数-PACF" class="headerlink" title="2.2.3 偏自相关函数(PACF)"></a>2.2.3 偏自相关函数(PACF)</h4><p>${\quad}$假设对于上证综指价格序列，一阶自相关系数大于0，说明今天的价格与昨天的价格相关，而昨天价格又与前一日价格相关，依次类推，可见当你计算今天与昨天价格之间的自相关系数时，同时包含了更早之前所有各期的信息对今天的间接影响，度量的是过去所有信息加总的影响效果。为了剔除其他各期的影响，单纯考察过去某一单期对今天的影响，引入偏自相关函数（Partial Autocorrelation Coefficient，简称PACF），即条件自相关系数，使用数学公式表示为：<br><br>偏自相关函数可以通过自回归模型（后续关于时间序列建模会进一步分析）来表述和求解，用<br>$$PACF_k = Corr(X_t,X_{t-k}|X_(t-1),X_(t-1),…,X_(t-k+1))$$<br>表示k阶自回归式中第j个回归系数，则k阶自回归模型表示为${\Phi_{kj}}$ <br><br>$$X_t = \Phi_{k1}X_{t-1} + \Phi_{k2}X_{t-2} + … + \Phi_{kk}X_{t-k} $$<br>若把最后一个系数${\Phi_{kk}}$看作滞后期k的函数。则称${\Phi_{kk}}$为偏自相关函数。${\Phi_{kk}}$自相关系数和偏自相关系数越大，说明过去对现在的影响越大。<br></p>
<h4 id="2-2-4-时间序列平稳性的判断方法"><a href="#2-2-4-时间序列平稳性的判断方法" class="headerlink" title="2.2.4 时间序列平稳性的判断方法"></a>2.2.4 时间序列平稳性的判断方法</h4><br>

<blockquote>
<p><strong>强平稳（Strictly Stationary）</strong> <br><br>${\quad}$强平稳要求时间序列随着时间的推移，其统计性质保持不变。强平稳是一个很强的条件，要求该时间序列的任何统计性质都不会随着时间发生变化。强平稳由于条件苛刻，理论和实证上都难以检验，因此现实中几乎无法运用。<br><br><br></p>
</blockquote>
<blockquote>
<p><strong>弱平稳（Weakly Stationary）</strong><br><br>${\quad}$弱平稳放宽了平稳性条件，只要求低阶矩平稳，即数学期望（均值）和方差不随时间和位置变化。弱平稳过程的条件是：<br><br>${\quad}$（1）均值函数在所有时间上恒为常数；<br><br>${\quad}$（2）存在二阶矩；<br><br>${\quad}$（3）对于所有时间t和和时滞k，自协方差相同。<br><br>${\quad}$值得注意的是，强平稳和弱平稳时间序列二者并没有包含关系。换句话说，强平稳时间序列不一定是弱平稳的，因为强平稳过程不一定存在二阶距；弱平稳时间序列也不一定是强平稳过程，因为弱平稳只能保证一阶矩和二阶距不随时间变化，但不能保证其有穷维分布不随时间变化。弱平稳的正态分布时间序列必定是强平稳的。因为正态分布的概率密度是由均值函数和自相关函数完全确定的，即如果均值函数和自相关函数不随时间变化，则概率密度函数也不随时间变化。<br><br><br></p>
</blockquote>
<blockquote>
<p><strong>时间序列平稳性的判断方法</strong><br><br>${\quad}$通过时序图的图形观察和单位根检验可以判断时间序列是否平稳，具体如下：<br><br>${\quad}$（1）观察时间序列图的形状来初步判断其平稳性<br><br>根据弱平稳的定义，时间序列的均值和方差为常数，因此其时序图应该围绕某一水平线上下以大致相同的幅度波动。如果该时序图存在明显递增、递减或周期性波动，则该时间序列很可能是不平稳的。<br><br>${\quad}$（2）观察序列的自相关和偏自相关函数图对于平稳时间序列而言，其自相关或偏自相关系数一般会快速减小至0附近或者在某一阶后变为0，而非平稳的时间序列的自相关系数一般是缓慢下降而不是快速减小。<br><br>${\quad}$（3）单位根检验。通过观察时序图、自相关和偏自相关图来判断时间序列平稳性，可能出现因观察者对图形的判断不同而得出不同的结论，为了更加客观的考察时间序列的平稳性，引入统计检验方法，即单位根检验。常见的单位根检验方法有DF检验（Dickey-Fuller Test）、ADF检验（AuGMENTED Dickey-Fuller Test）和PP检验（Phillips-Perron Test）。关于单位根检验和DF、ADF、PP检验的公式原理此处不详细展开，可参考本科计量经济学教材的时间序列分析部分。<br></p>
</blockquote>
<h2 id="三、时间序列分析的常用统计模型"><a href="#三、时间序列分析的常用统计模型" class="headerlink" title="三、时间序列分析的常用统计模型"></a>三、时间序列分析的常用统计模型</h2><h3 id="时间序列预测的程序"><a href="#时间序列预测的程序" class="headerlink" title="时间序列预测的程序"></a>时间序列预测的程序</h3><p>$\qquad$时间序列分析的主要目的之一是根据已有的历史数据对未来进行预测。时间序列含有不同的成分，如趋势、季节性、周期性和随机性。对于一个具体的时间序列，它可能含有一种成分，也可能同时含有几种成分，含有不同成分的时间序列所用的预测方法是不同的。预测步骤：</p>
<ul>
<li>第一步：确定时间序列所包含的成分，确定时间序列的类型</li>
<li>第二步：找出适合此类时间序列的预测方法</li>
<li>第三步：对可能的预测方法进行评估，以确定最佳预测方案</li>
<li>第四步：利用最佳预测方案进行预测</li>
</ul>
<h3 id="3-1-常用的时间序列模型"><a href="#3-1-常用的时间序列模型" class="headerlink" title="3.1 常用的时间序列模型"></a>3.1 常用的时间序列模型</h3><p><img src="model.png" srcset="/walker_sue/img/loading.gif"></p>
<h4 id="3-1-1-自回归AR-p-模型"><a href="#3-1-1-自回归AR-p-模型" class="headerlink" title="3.1.1 自回归AR(p)模型"></a>3.1.1 自回归AR(p)模型</h4><p>Auto Regressive，中文叫自回归模型。认为过去若干时刻的点通过线性组合，再加上白噪声就可以预测未来某个时刻的点。日常生活环境中就存在白噪声，在数据挖掘的过程中，可以把它理解为一个期望为0，方差为常数的纯随机过程。AR模型存在一个阶数p，称为AR(p)模型，也叫作p阶自回归模型。指的是通过这个时刻点的前p个点，通过线性组合再加上白噪声来预测当前时刻点的值。<br>$${X_t = c + \sum^p_{i=1}{\phi_i}X_{t-i}+ {\epsilon_t}}$$<br>自回归模型描述的是当前值与历史值之间的关系。<br></p>
<h4 id="3-1-2-移动平均MA-q-模型"><a href="#3-1-2-移动平均MA-q-模型" class="headerlink" title="3.1.2 移动平均MA(q)模型"></a>3.1.2 移动平均MA(q)模型</h4><p>Moving Average，中文叫做滑动平均模型。与AR模型大同小异，AR模型是历史时序值的线性组合，MA是通过历史白噪声进行线性组合来影响当前时刻点。MA模型中的历史白噪声是通过影响历史时序值，从而间接影响到当前时刻点的预测值。MA模型存在一个阶数q，称为MA(q)模型，也叫作q阶移动平均模型。AR和MA模型都存在阶数，在AR模型中，用p表示，在MA模型中用q表示，这两个模型大同小异，与AR模型不同的是MA模型是历史白噪声的线性组合。<br>$${X_t = \mu + {\epsilon_t} + \sum^q_{i=1}{\theta_i}\epsilon_{t-i}}$$<br>移动平均模型描述的是自回归部分的误差累计。 <br></p>
<h4 id="3-1-3-ARMA-p-q-模型"><a href="#3-1-3-ARMA-p-q-模型" class="headerlink" title="3.1.3 ARMA(p,q)模型"></a>3.1.3 ARMA(p,q)模型</h4><p>Auto Regressive Moving Average，中文叫做自回归滑动平均模型。AR模型和MA模型的混合，相比AR模型和MA模型，它有更准确的估计。ARMA模型存在p和q两个阶数，称为ARMA(p,q)模型：自回归模型结合了两个模型的特点，AR解决当前数据与后期数据之间的关系，MA则可以解决随机变动，即噪声问题。ARMA(p,q)模型可以表示为：<br>$${X_t = c + {\epsilon_t} + \sum^p_{i=1}{\phi_i}X_{t-i} + \sum^q_{i=1}{\theta_i}\epsilon_{t-i}}$$<br>当q=0时，是AR(p)模型<br>当p=0时，是MA(q)模型</p>
<h4 id="3-1-4-ARIMA模型"><a href="#3-1-4-ARIMA模型" class="headerlink" title="3.1.4 ARIMA模型"></a>3.1.4 ARIMA模型</h4><p>Auto Regressive Integrated Moving Average模型，中文叫差分自回归滑动平均模型，也叫求合自回归滑动平均模型。<br>相比于ARMA，ARIMA多了一个差分的过程，作用是对不平稳数据进行差分平稳，在差分平稳后再进行建模。<br>ARIMA的原理和ARMA模型一样。相比于ARMA(p,q)的两个阶数，ARIMA是一个三元组的阶数(p,d,q)，称为ARIMA(p,d,q)模型，其中d是差分阶数。<br>AR，MA是ARMA的特殊形式，而ARMA是ARIMA的特殊形式。<br><br>ARIMA模型步骤：<br></p>
<ul>
<li>Step1，观察时间序列数据，是否为平稳序列</li>
<li>Step2，对于非平稳时间序列要先进行d阶差分运算，化为平稳时间序列</li>
<li>Step3，使用ARIMA（p, d, q）模型进行训练拟合，找到最优的(p, d, q)。及训练好的模型，ARIMA（p，d，q）中，AR是”自回归”，p为自回归项数；MA为”滑动平均”，q为滑动平均项数，d为使之成为平稳序列所做的差分次数（阶数）</li>
<li>Step4，使用训练好的ARIMA模型进行预测，并对差分进行还原</li>
</ul>
<p>ARIMA 用差分将不平稳数据先变得平稳，再用ARMA模型。关于差分：差分=序列之间做差值，目的是为了得到平稳的序列，也就是去掉前面数值的影响，一次差分为序列之间做一次差值，二次差分为在一次差分的基础上在做一次差分。若x=[1,4,9,16,25….]（x有二次趋势）。</p>
<h3 id="3-2-模型评估方法"><a href="#3-2-模型评估方法" class="headerlink" title="3.2 模型评估方法"></a>3.2 模型评估方法</h3><p>$\qquad$在选择某种特定的方法进行预测时，需要评价该方法的预测效果或准确性。评价方法是找出预测值与实际值的差距，即预测误差。最优的预测方法就是预测误差达到最小的方法。预测误差计算方法：平均误差，平均绝对误差、均方误差、平均百分比误差、平均绝对百分比误差。方法的选择取决于预测者的目标、对方法的熟悉程度。<br><br>（1）平均误差（mean error）:Y:观测值，F：预测值，n预测值个数<br><br>由于预测误差的数值可能有正有负，求和的结果就会相互抵消，这种情况下，平均误差可能会低估误差。<br></p>
<p>$$ME = \frac{\sum^{n}_{i=1}(Y_i - F_i)}{n}$$ <br><br>（2）平均绝对误差（mean absolute deviation）是将预测误差取绝对值后计算的平均无擦，MAD：<br></p>
<p>$$MAD = \frac{\sum^{n}_{i=1}|Y_i - F_i|}{n}$$ <br><br>平均绝对误差可避免误差相互抵消的问题，因而可以准确反映实际预测误差的大小。<br><br>（3）均方误差（mean square error）:通过平方消去误差的正负号后计算的平均误差，MSE:<br></p>
<p>$$MSE = \frac{\sum^{n}_{i=1}(Y_i - F_i)^2}{n}$$ <br><br>（4）平均百分比误差和平均绝对百分比误差<br></p>
<p>$$MPE = \frac{\sum^{n}_{i=1}(\frac{Y_i - F_i}{Y_i}*100)}{n}$$ <br><br>$$MAPE = \frac{\sum^{n}_{i=1}(\frac{|Y_i - F_i|}{Y_i}*100)}{n}$$ <br><br>ME,MAD,MSE的大小受时间序列数据的水平和计量单位的影响，有时并不能真正反映预测模型的好坏，只有在比较不同模型对同一数据的预测时才有意义。平均百分比误差（mean percentage error，MPE）和平均绝对百分比误差（mean absolute percentage error,MAPE）则不同，它们消除了时间序列数据的水平和计量单位的影响，是反映误差大小的相对值。<br></p>
<h2 id="四、LSTM进行时间序列预测"><a href="#四、LSTM进行时间序列预测" class="headerlink" title="四、LSTM进行时间序列预测"></a>四、LSTM进行时间序列预测</h2><p>$\qquad$LSTM，Long Short-Term Memory，长短记忆网络。可以避免常规RNN的梯度消失，在工业界有广泛应用。引入了三个门函数：输入门（Input Gate）、遗忘门（Forget Gate）和输出门（Output Gate）来控制输入值、记忆值和输出值。输入门决定了当前时刻网络的状态有多少信息需要保存到内部状态中，遗忘门决定了过去的状态信息有多少需要丢弃 =&gt; 输入门和遗忘门是LSTM能够记忆长期依赖的关键。输出门决定当前时刻的内部状态有多少信息需要输出给外部状态。<br><img src="lstm.png" srcset="/walker_sue/img/loading.gif"></p>
<h2 id="五、PM2-5数据基于时序预测的实现"><a href="#五、PM2-5数据基于时序预测的实现" class="headerlink" title="五、PM2.5数据基于时序预测的实现"></a>五、PM2.5数据基于时序预测的实现</h2><pre><code class="hljs python"><span class="hljs-keyword">from</span> pandas <span class="hljs-keyword">import</span> DataFrame, concat, read_csv
<span class="hljs-keyword">from</span> keras.models <span class="hljs-keyword">import</span> Sequential
<span class="hljs-keyword">from</span> keras.layers <span class="hljs-keyword">import</span> LSTM, Dense
<span class="hljs-keyword">from</span> keras.optimizers <span class="hljs-keyword">import</span> SGD
<span class="hljs-keyword">from</span> sklearn.preprocessing <span class="hljs-keyword">import</span> LabelEncoder, MinMaxScaler
<span class="hljs-keyword">from</span> matplotlib <span class="hljs-keyword">import</span> pyplot <span class="hljs-keyword">as</span> plt
<span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime
 

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">prase</span>(<span class="hljs-params">x</span>):</span>
    <span class="hljs-keyword">return</span> datetime.strptime(x, <span class="hljs-string">&#x27;%Y %m %d %H&#x27;</span>)
 

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">load_dataset</span>(<span class="hljs-params">filename</span>):</span>
    <span class="hljs-comment">#</span>
    dataset = read_csv(filename, parse_dates=[[<span class="hljs-string">&#x27;year&#x27;</span>, <span class="hljs-string">&#x27;month&#x27;</span>, <span class="hljs-string">&#x27;day&#x27;</span>, <span class="hljs-string">&#x27;hour&#x27;</span>]], index_col=<span class="hljs-number">0</span>, date_parser=prase)

    <span class="hljs-comment"># 删除No列</span>
    dataset.drop(<span class="hljs-string">&#x27;No&#x27;</span>, axis=<span class="hljs-number">1</span>, inplace=<span class="hljs-literal">True</span>)

    <span class="hljs-comment"># 设定列名</span>
    dataset.columns = [<span class="hljs-string">&#x27;pollution&#x27;</span>, <span class="hljs-string">&#x27;dew&#x27;</span>, <span class="hljs-string">&#x27;temp&#x27;</span>, <span class="hljs-string">&#x27;press&#x27;</span>, <span class="hljs-string">&#x27;wnd_dir&#x27;</span>, <span class="hljs-string">&#x27;wnd_spd&#x27;</span>, <span class="hljs-string">&#x27;snow&#x27;</span>, <span class="hljs-string">&#x27;rain&#x27;</span>]
    dataset.index.name = <span class="hljs-string">&#x27;date&#x27;</span>

    <span class="hljs-comment"># 使用中位数填充缺失值</span>
    dataset[<span class="hljs-string">&#x27;pollution&#x27;</span>].fillna(dataset[<span class="hljs-string">&#x27;pollution&#x27;</span>].mean(), inplace=<span class="hljs-literal">True</span>)

    <span class="hljs-keyword">return</span> dataset</code></pre>
<pre><code class="hljs python"><span class="hljs-comment"># convert series to supervised learning</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">convert_dataset</span>(<span class="hljs-params">data, n_input=<span class="hljs-number">1</span>, out_index=<span class="hljs-number">0</span>, dropnan=<span class="hljs-literal">True</span></span>):</span>
    n_vars = <span class="hljs-number">1</span> <span class="hljs-keyword">if</span> <span class="hljs-built_in">type</span>(data) <span class="hljs-keyword">is</span> <span class="hljs-built_in">list</span> <span class="hljs-keyword">else</span> data.shape[<span class="hljs-number">1</span>]
    df = DataFrame(data)
    cols, names = [], []
    <span class="hljs-comment"># 输入序列（t-n,...,t-1）</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n_input, <span class="hljs-number">0</span>, -<span class="hljs-number">1</span>):
        cols.append(df.shift(i))
        names += [(<span class="hljs-string">&#x27;var%d(t-%d)&#x27;</span> % (j + <span class="hljs-number">1</span>, i)) <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n_vars)]

    <span class="hljs-comment"># 输出结果t</span>
    cols.append(df[df.columns[out_index]])
    names += [<span class="hljs-string">&#x27;result&#x27;</span>]
    <span class="hljs-comment"># 合并输入输出序列</span>
    result = concat(cols, axis=<span class="hljs-number">1</span>)
    result.columns = names

    <span class="hljs-comment"># 删除包含缺失值的行</span>
    <span class="hljs-keyword">if</span> dropnan:
        result.dropna(inplace=<span class="hljs-literal">True</span>)
    <span class="hljs-keyword">return</span> result
 
<span class="hljs-comment"># class_indexs编码字段序列号，或者序列号list，列表从0开始</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">class_encode</span>(<span class="hljs-params">data, class_indexs</span>):</span>
    encoder = LabelEncoder()
    class_indexs = class_indexs <span class="hljs-keyword">if</span> <span class="hljs-built_in">type</span>(class_indexs) <span class="hljs-keyword">is</span> <span class="hljs-built_in">list</span> <span class="hljs-keyword">else</span> [class_indexs]
    values = DataFrame(data).values

    <span class="hljs-keyword">for</span> index <span class="hljs-keyword">in</span> class_indexs:
        values[:, index] = encoder.fit_transform(values[:, index])

    <span class="hljs-keyword">return</span> DataFrame(values) <span class="hljs-keyword">if</span> <span class="hljs-built_in">type</span>(data) <span class="hljs-keyword">is</span> DataFrame <span class="hljs-keyword">else</span> values
 

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">build_model</span>(<span class="hljs-params">lstm_input_shape</span>):</span>
    model = Sequential()
    model.add(LSTM(units=<span class="hljs-number">50</span>, input_shape=lstm_input_shape, return_sequences=<span class="hljs-literal">True</span>))
    model.add(LSTM(units=<span class="hljs-number">50</span>, dropout=<span class="hljs-number">0.2</span>, recurrent_dropout=<span class="hljs-number">0.2</span>,return_sequences=<span class="hljs-literal">True</span>))
    model.add(LSTM(units=<span class="hljs-number">50</span>, dropout=<span class="hljs-number">0.2</span>, recurrent_dropout=<span class="hljs-number">0.2</span>,return_sequences=<span class="hljs-literal">True</span>))
    model.add(LSTM(units=<span class="hljs-number">50</span>, dropout=<span class="hljs-number">0.2</span>, recurrent_dropout=<span class="hljs-number">0.2</span>,return_sequences=<span class="hljs-literal">True</span>))
    model.add(LSTM(units=<span class="hljs-number">50</span>, dropout=<span class="hljs-number">0.2</span>, recurrent_dropout=<span class="hljs-number">0.2</span>))
    model.add(Dense(<span class="hljs-number">1</span>))
    model.<span class="hljs-built_in">compile</span>(loss=<span class="hljs-string">&#x27;mae&#x27;</span>, optimizer=<span class="hljs-string">&#x27;adam&#x27;</span>)
    model.summary()
    <span class="hljs-keyword">return</span> model

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sample_model</span>(<span class="hljs-params">lstm_input_shape</span>):</span>
    <span class="hljs-comment"># 设置网络格式</span>
    model = Sequential()
    model.add(LSTM(<span class="hljs-number">64</span>, input_shape=lstm_input_shape))
    model.add(Dense(<span class="hljs-number">1</span>))
    model.<span class="hljs-built_in">compile</span>(optimizer=<span class="hljs-string">&quot;adam&quot;</span>, loss=<span class="hljs-string">&quot;mse&quot;</span>)
    model.summary()
    <span class="hljs-keyword">return</span> model

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">plot_imag</span>(<span class="hljs-params">source_data_set, train_pred, test_pred</span>):</span>
    fig = plt.figure(figsize=(<span class="hljs-number">12</span>,<span class="hljs-number">4</span>),dpi=<span class="hljs-number">150</span>)
    plt.plot(source_data_set[:, -<span class="hljs-number">1</span>], label=<span class="hljs-string">&quot;real&quot;</span>, c=<span class="hljs-string">&quot;b&quot;</span>, alpha=<span class="hljs-number">1</span>)
    plt.plot([x <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> train_pred], label=<span class="hljs-string">&quot;train_pred&quot;</span>, c=<span class="hljs-string">&quot;g&quot;</span>, alpha=<span class="hljs-number">0.7</span>)
    tmp = [<span class="hljs-literal">None</span> <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> train_pred] + [x <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> test_pred]
    tmp = [[x] <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> tmp]
    plt.plot(tmp, label=<span class="hljs-string">&quot;test_pred&quot;</span>, c=<span class="hljs-string">&quot;r&quot;</span>, alpha=<span class="hljs-number">0.7</span>)
    plt.legend(loc=<span class="hljs-number">0</span>)
    plt.show()</code></pre>
<pre><code class="hljs python"><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&#x27;__main__&#x27;</span>:
    filename = <span class="hljs-string">&#x27;../pm2.5/raw.csv&#x27;</span>
    data = load_dataset(filename)
    <span class="hljs-comment"># 第4列风向数据进行labelencoder</span>
    data = class_encode(data, <span class="hljs-number">4</span>)
    <span class="hljs-comment"># 生成数据集，使用前5次的数据来预测新数据</span>
<span class="hljs-comment">#     dataset = convert_dataset(data, 1, 0)</span>
    dataset = convert_dataset(data, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>)
    values =  dataset.values.astype(<span class="hljs-string">&quot;float32&quot;</span>) <span class="hljs-comment"># 确保数据格式为float类型</span>
    values = values[<span class="hljs-number">24</span>:,] <span class="hljs-comment"># 第一天数据有问题，剔除</span>
    <span class="hljs-comment"># </span>
    scaler = MinMaxScaler(feature_range=(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>))
    values = scaler.fit_transform(values)
    
    <span class="hljs-comment"># 超参数设定</span>
    batch_size = <span class="hljs-number">32</span>
    epochs = <span class="hljs-number">20</span>
    train_size = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">len</span>(values)*<span class="hljs-number">0.8</span>)

    <span class="hljs-comment"># 分类训练数据集和评估数据集</span>
    train = values[:train_size, :]
    validation = values[train_size:, :]
    x_train, y_train = train[:, :-<span class="hljs-number">1</span>], train[:, -<span class="hljs-number">1</span>]
    x_validation,y_validation = validation[:,:-<span class="hljs-number">1</span>],validation[:,-<span class="hljs-number">1</span>]

    <span class="hljs-comment">#数据归一化</span>
<span class="hljs-comment">#     scalar = MinMaxScaler(feature_range=(0, 1))</span>
<span class="hljs-comment">#     x_train = scalar.fit_transform(x_train)</span>
<span class="hljs-comment">#     x_validation =scalar.fit_transform(x_validation)</span>
    <span class="hljs-comment">#将数据整理成[样本，时间步长，特征]结构</span>
    x_train = x_train.reshape(x_train.shape[<span class="hljs-number">0</span>],n_input,x_train.shape[<span class="hljs-number">1</span>])
    x_validation = x_validation.reshape(x_validation.shape[<span class="hljs-number">0</span>],<span class="hljs-number">1</span>,x_validation.shape[<span class="hljs-number">1</span>])
    <span class="hljs-comment">#查看数据维度</span>
    print(x_train.shape,y_train.shape,x_validation.shape,y_validation.shape)

    <span class="hljs-comment">#train</span>
    lstm_input_shape=(x_train.shape[<span class="hljs-number">1</span>],x_train.shape[<span class="hljs-number">2</span>])
    model = build_model(lstm_input_shape=lstm_input_shape)
<span class="hljs-comment">#     model = sample_model(lstm_input_shape=lstm_input_shape)</span>
    model.fit(x_train,y_train,batch_size=batch_size,validation_data=(x_validation,y_validation),
              epochs=epochs,verbose=<span class="hljs-number">2</span>,shuffle=<span class="hljs-literal">False</span>)
    <span class="hljs-comment"># predict</span>
    train_pred = model.predict(x_train)
    test_pred = model.predict(x_validation)
    <span class="hljs-comment"># fit plot</span>
    plot_imag(values, train_pred, test_pred)</code></pre>
<pre><code class="hljs python"><span class="hljs-comment"># calculate RMSE</span>
<span class="hljs-keyword">from</span> sklearn.metrics <span class="hljs-keyword">import</span> mean_squared_error
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
<span class="hljs-comment"># rmse = np.sqrt(mean_squared_error(y_validation, test_pred))</span>
<span class="hljs-comment"># print(y_validation[:100], test_pred[:100])</span>
print(<span class="hljs-string">&#x27;Train RMSE: %.3f&#x27;</span> % np.sqrt(mean_squared_error(y_train, train_pred)))
print(<span class="hljs-string">&#x27;Test RMSE: %.3f&#x27;</span> % np.sqrt(mean_squared_error(y_validation, test_pred)))</code></pre>
<pre><code class="hljs python"><span class="hljs-comment"># 数据还原</span>
tmp = values.copy()
<span class="hljs-comment"># tmp[:,-1] = train_pred + test_pred</span>
tmp[:,-<span class="hljs-number">1</span>] = <span class="hljs-built_in">list</span>(train_pred) + <span class="hljs-built_in">list</span>(test_pred) <span class="hljs-comment"># 预测数据还原</span>

values_tr = scaler.inverse_transform(values) <span class="hljs-comment"># 真实数据还原</span>
values_tr[:, -<span class="hljs-number">1</span>]

<span class="hljs-comment">#fit plot</span>
plot_imag(values_tr, tmp_tr[:, -<span class="hljs-number">1</span>][:train_size],  tmp_tr[:, -<span class="hljs-number">1</span>][train_size:])

<span class="hljs-comment"># MSE</span>
print(<span class="hljs-string">&#x27;Train RMSE: %.3f&#x27;</span> % np.sqrt(mean_squared_error(values_tr[:, -<span class="hljs-number">1</span>][:train_size], tmp_tr[:, -<span class="hljs-number">1</span>][:train_size])))
print(<span class="hljs-string">&#x27;Test RMSE: %.3f&#x27;</span> % np.sqrt(mean_squared_error(values_tr[:, -<span class="hljs-number">1</span>][train_size:], tmp_tr[:, -<span class="hljs-number">1</span>][train_size:])))</code></pre>
<h2 id="六、时序数据库"><a href="#六、时序数据库" class="headerlink" title="六、时序数据库"></a>六、时序数据库</h2><p>时间序列数据库（Time Series Database)，A time series database (TSDB) is a software system that is optimized for handling time series data, arrays of numbers indexed by time (a datetime or a datetime range)。以上是维基百科对于时序数据库的定义。可以把它拆解成3个方面来看：<strong>时序特性，数据特性，数据库特性</strong>。<br><br></p>
<blockquote>
<p><strong>时序特性:</strong></p>
</blockquote>
<ul>
<li>时间戳：通用的业务场景内以秒和毫秒精度为主，在一些遥感等高频采集领域，时间戳可以达到纳秒级别。时间戳种类包括unix系统时间戳和Calendar, 并且支持时区的自动适配。</li>
<li>采样频率：采集频率一般有2种，一种是周期性的时间采样频率，比如服务器性能相关的定期汇总指标。另外一种是离散型的采样，比如网站的访问等等</li>
</ul>
<blockquote>
<p><strong>数据特性:</strong></p>
</blockquote>
<ul>
<li>数据顺序追加</li>
<li>数据可多维关联</li>
<li>通常高频访问热数据</li>
<li>冷数据需要降维归档</li>
<li>数据主要覆盖数值，状态，事件</li>
</ul>
<blockquote>
<p><strong>数据库特性（CRUD）:</strong></p>
</blockquote>
<ul>
<li>写入速率稳定并且远远大于读取</li>
<li>按照时间窗口访问数据</li>
<li>极少更新，存在一定窗口期的覆盖写</li>
<li>批量删除</li>
<li>具备通用数据库要求的高可用，高可靠，可伸缩特性</li>
<li>通常不需要具备事务的能力</li>
</ul>
<p>时序数据库的选择需要我们结合具体的业务需求，一般来说考虑这个几个因素：<strong>数据模型、查询语言、稳定性、性能、生态、操作性以及支持</strong>：</p>
<ul>
<li><strong>数据模型:</strong><br>时间序列数据模型一般有两种，一种无schema，具有多tag的模型，还有一种name、timestamp、value型。前者适合多值模式，对复杂业务模型更适合。后者更适合单维数据模型。</li>
<li><strong>查询语言:</strong><br>目前大部分TSDB都支持基于HTTP的SQL-like查询。</li>
<li><strong>稳定性:</strong><br>可用性主要体现在系统的稳定高可用上，以及数据的高可用存储上。一个优秀的系统，应该有一个优雅而高可用的架构设计。简约而稳定。</li>
<li><strong>性能:</strong><br>性能是我们必须考虑的因素。当我们开始考虑更细分领域的数据存储时，除了数据模型的需求之外，很大的原因都是通用的数据库系统在性能上无法满足我们的需求。大部分时间序列库倾向写多读少场景，用户需要平衡自身的需求。下面会有一份各库的性能对比，大家可以做一个参考。</li>
<li><strong>生态:</strong><br>生态是我们选择一个开源组件必须认真考虑的问题。一个生态优秀的系统，使用的人多了，未被发现的坑也将少了。另外在使用中遇到问题，求助于社区，往往可以得到一些比较好的解决方案。另外好的生态，其周边边界系统将十分成熟，这让我们在对接其他系统时会有更多成熟的方案。</li>
<li><strong>操作性:</strong><br>易于运维，易于操作。</li>
<li><strong>支持:</strong><br>一个系统其背后的支持公司也是比较重要的。背后有一个强大的公司或组织，这在项目可用性保证和后期维护更新上都会有较大的体验。</li>
</ul>
<blockquote>
<p><strong>参考资料</strong></p>
<ul>
<li>开课吧BI学习课件-陈旸 时间序列分析</li>
</ul>
</blockquote>
<ul>
<li><a target="_blank" rel="noopener" href="https://www.math.pku.edu.cn/teachers/lidf/course/atsa/atsanotes/html/_atsanotes/index.html">应用时间序列分析备课笔记(R语言版本)，非常详细！！</a></li>
<li><a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_38784098/article/details/86620018">时间序列及相关算法（AR，MA，ARMA）分析</a></li>
<li><a target="_blank" rel="noopener" href="https://blog.csdn.net/mengjizhiyou/article/details/82683448">时间序列分析和预测(含实例及代码)</a></li>
<li><a target="_blank" rel="noopener" href="https://www.jianshu.com/p/014b1e0ad0fe">【Python量化基础】时间序列的自相关性与平稳性</a></li>
<li><a target="_blank" rel="noopener" href="https://www.jianshu.com/p/124010e961e4">时间序列ARMA</a></li>
<li><a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/338811720">时间数据库的前生今世</a></li>
</ul>
<pre><code class="hljs python"></code></pre>
            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/walker_sue/categories/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/">机器学习</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/walker_sue/tags/BI/">BI</a>
                    
                      <a class="hover-with-bg" href="/walker_sue/tags/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/">机器学习</a>
                    
                      <a class="hover-with-bg" href="/walker_sue/tags/%E6%97%B6%E9%97%B4%E5%BA%8F%E5%88%97%E5%88%86%E6%9E%90/">时间序列分析</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">本博客所有文章除特别声明外，均采用 <a target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！</p>
              
              
                <div class="post-prevnext row">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/walker_sue/2021/01/19/BI-week2-Prophet/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">时间序列分析（二）Prophet</span>
                        <span class="visible-mobile">Vorheriger</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/walker_sue/2020/11/05/NLP_week1/">
                        <span class="hidden-mobile">NLP阅读理解Week1 学习笔记</span>
                        <span class="visible-mobile">Nächster</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;TOC</p>
  <div id="tocbot"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    
  </main>

  
    <a id="scroll-top-button" href="#" role="button">
      <i class="iconfont icon-arrowup" aria-hidden="true"></i>
    </a>
  

  
    <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">Suchen</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">Stichwort</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
  

  

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
     <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
  </div>
  

  

  
</footer>

<!-- SCRIPTS -->
<script  src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js" ></script>
<script  src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js" ></script>
<script  src="/walker_sue/js/debouncer.js" ></script>
<script  src="/walker_sue/js/main.js" ></script>

<!-- Plugins -->


  
    <script  src="/walker_sue/js/lazyload.js" ></script>
  



  



  <script defer src="https://cdn.staticfile.org/clipboard.js/2.0.6/clipboard.min.js" ></script>
  <script  src="/walker_sue/js/clipboard-use.js" ></script>







  <script  src="https://cdn.staticfile.org/tocbot/4.11.1/tocbot.min.js" ></script>
  <script>
    $(document).ready(function () {
      var boardCtn = $('#board-ctn');
      var boardTop = boardCtn.offset().top;

      tocbot.init({
        tocSelector: '#tocbot',
        contentSelector: '#post-body',
        headingSelector: 'h1,h2,h3,h4,h5,h6',
        linkClass: 'tocbot-link',
        activeLinkClass: 'tocbot-active-link',
        listClass: 'tocbot-list',
        isCollapsedClass: 'tocbot-is-collapsed',
        collapsibleClass: 'tocbot-is-collapsible',
        collapseDepth: 0,
        scrollSmooth: true,
        headingsOffset: -boardTop
      });
      if ($('.toc-list-item').length > 0) {
        $('#toc').css('visibility', 'visible');
      }
    });
  </script>



  <script  src="https://cdn.staticfile.org/typed.js/2.0.11/typed.min.js" ></script>
  <script>
    function typing(id, title){
        var typed = new Typed('#' + id, {
            strings: [
              '  ',
              title + "&nbsp;",
            ],
            cursorChar: "_",
            typeSpeed: 70,
            loop: false,
        });
        typed.stop();
        $(document).ready(function () {
            $(".typed-cursor").addClass("h2");
            typed.start();
        });
    }
    
        typing("subtitle", "时间序列分析（一）")
    
  </script>


  <script  src="https://cdn.staticfile.org/anchor-js/4.2.2/anchor.min.js" ></script>
  <script>
    anchors.options = {
      placement: "right",
      visible: "hover",
      
    };
    var el = "h1,h2,h3,h4,h5,h6".split(",");
    var res = [];
    for (item of el) {
      res.push(".markdown-body > " + item)
    }
    anchors.add(res.join(", "))
  </script>



  <script  src="/walker_sue/js/local-search.js" ></script>
  <script>
    var path = "/walker_sue/local-search.xml";
    var inputArea = document.querySelector("#local-search-input");
    inputArea.onclick = function () {
      searchFunc(path, 'local-search-input', 'local-search-result');
      this.onclick = null
    }
  </script>



  <script  src="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.css" />

  <script>
    $('#post img:not(.no-zoom img, img[no-zoom]), img[zoom]').each(
      function () {
        var element = document.createElement('a');
        $(element).attr('data-fancybox', 'images');
        $(element).attr('href', $(this).attr('src'));
        $(this).wrap(element);
      }
    );
  </script>





  

  
    <!-- MathJax -->
    <script>
      MathJax = {
        tex: {
          inlineMath: [['$', '$'], ['\\(', '\\)']]
        },
        options: {
          renderActions: {
            findScript: [10, doc => {
              document.querySelectorAll('script[type^="math/tex"]').forEach(node => {
                const display = !!node.type.match(/; *mode=display/);
                const math = new doc.options.MathItem(node.textContent, doc.inputJax[0], display);
                const text = document.createTextNode('');
                node.parentNode.replaceChild(text, node);
                math.start = { node: text, delim: '', n: 0 };
                math.end = { node: text, delim: '', n: 0 };
                doc.math.push(math);
              });
            }, '', false],
            insertedScript: [200, () => {
              document.querySelectorAll('mjx-container').forEach(node => {
                let target = node.parentNode;
                if (target.nodeName.toLowerCase() === 'li') {
                  target.parentNode.classList.add('has-jax');
                }
              });
            }, '', false]
          }
        }
      };
    </script>

    <script async src="https://cdn.staticfile.org/mathjax/3.0.5/es5/tex-svg.js" ></script>

  











</body>
</html>
